package org.six11.ss.client;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.List;
import java.util.Map;

import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

import org.six11.ss.shared.Message;
import org.six11.util.Debug;
import org.six11.util.adt.MultiState;

/**
 * 
 * 
 * @author Gabe Johnson <johnsogg@cmu.edu>
 */
public class RoomPanel extends JPanel {

  private static final String CREATE_ROOM_STR = "Create a room...";

  protected MultiState state;
  protected JLabel instructions;
  protected JPanel list;
  private ActionListener joinRoomAction;

  public RoomPanel(MultiState ms) {
    this.state = ms;
    joinRoomAction = new ActionListener() {
      @SuppressWarnings("unchecked")
      public void actionPerformed(ActionEvent ev) {
        String roomName = ev.getActionCommand();
        if (roomName.equals(CREATE_ROOM_STR)) {
          promptNewRoomName();
        } else {
          sendJoinRoom(roomName);
        }
      }
    };
    setBackground(Color.WHITE);
    state.addChangeListener(ClientStateNames.K_ROOM_LIST, new PropertyChangeListener() {
      public void propertyChange(PropertyChangeEvent evt) {
        rebuildList();
      }
    });
    instructions = new JLabel("Pick a room!");
    list = new JPanel();
    list.setBackground(Color.WHITE);
    list.setLayout(new GridLayout(0, 1));
    setLayout(new BorderLayout());
    add(instructions, BorderLayout.NORTH);
    add(list, BorderLayout.CENTER);
    rebuildList();
  }

  private void sendJoinRoom(String roomName) {
    Map<String, CommandHandler> commandHandlers = (Map<String, CommandHandler>) state
        .getValue(ClientStateNames.K_COMMAND_HANDLERS);
    Message msg = new Message("room");
    msg.addParam("operation", "join");
    msg.addParam("roomName", roomName);
    commandHandlers.get("default").sendMessage(msg);
  }

  private void promptNewRoomName() {
    String inputValue = JOptionPane.showInputDialog("New room name?");
    if (inputValue != null && inputValue.length() > 0) {
      sendJoinRoom(inputValue);
    }
  }

  /**
   * Rebuilds the list of rooms and their populations based on the current understanding keyed off
   * K_ROOM_LIST. It also provides a button to create a new room.
   */
  @SuppressWarnings("unchecked")
  protected void rebuildList() {
    bug("Rebuilding room list.");
    List<RoomInfo> roomInfo = (List<RoomInfo>) state.getValue(ClientStateNames.K_ROOM_LIST);
    list.removeAll();
    RoomInfo createRoom = new RoomInfo(CREATE_ROOM_STR, "fake", 0);
    list.add(makeRoomItem(createRoom));
    for (RoomInfo r : roomInfo) {
      list.add(makeRoomItem(r));
    }
    if (roomInfo.isEmpty()) {
      list.add(new JLabel("No room information is available."));
    }
    list.revalidate(); // necessary after changing components in a container
  }

  private JComponent makeRoomItem(RoomInfo r) {
    // TODO: eventually this should return a different kind of component (e.g. not a JButton)
    JButton ret = null;
    if (r.getId().equals("fake")) {
      ret = new JButton(r.getName());
    } else {
      ret = new JButton(r.getName() + " (" + r.getPopulation() + " players)");
    }
    ret.setActionCommand(r.getName());
    ret.addActionListener(joinRoomAction);
    return ret;
  }

  private void bug(String what) {
    Debug.out("RoomPanel", what);
  }

}
